package com.ruoyi.factorydata.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.factorydata.domain.ProcessCategory;
import com.ruoyi.factorydata.domain.ProcessData;
import com.ruoyi.factorydata.domain.ProcessMaterialRelation;
import com.ruoyi.factorydata.domain.ProcessStationRelation;
import com.ruoyi.factorydata.domain.dto.ProcessDataDTO;
import com.ruoyi.factorydata.domain.vo.ProcessDataVo;
import com.ruoyi.factorydata.mapper.ProcessCategoryMapper;
import com.ruoyi.factorydata.mapper.ProcessDataMapper;
import com.ruoyi.factorydata.mapper.ProcessMaterialRelationMapper;
import com.ruoyi.factorydata.mapper.ProcessStationRelationMapper;
import com.ruoyi.factorydata.service.IProcessDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工序信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-12
 */
@Slf4j
@Service
public class ProcessDataServiceImpl extends ServiceImpl<ProcessDataMapper, ProcessData> implements IProcessDataService {
    @Autowired
    private ProcessDataMapper processDataMapper;

    @Autowired
    private ProcessCategoryMapper processCategoryMapper;

    @Autowired
    private ProcessStationRelationMapper processStationRelationMapper;

    @Autowired
    private ProcessMaterialRelationMapper processMaterialRelationMapper;

    /**
     * 查询工序信息
     *
     * @param id 工序信息主键
     * @return 工序信息
     */
    @Override
    public ProcessDataVo selectProcessDataById(Long id) {
        ProcessData processData = processDataMapper.selectProcessDataById(id);
        ProcessCategory processCategory = processCategoryMapper.selectProcessCategoryById(processData.getCategoryId());
        List<ProcessStationRelation> processStationRelations = processStationRelationMapper.selectList(new QueryWrapper<ProcessStationRelation>().lambda()
                .eq(ProcessStationRelation::getProcessId, processData.getId()));
        log.info("processStationRelations:{}", processStationRelations);
        List<ProcessMaterialRelation> processMaterialRelations = processMaterialRelationMapper.selectList(new QueryWrapper<ProcessMaterialRelation>().lambda()
                .eq(ProcessMaterialRelation::getProcessId, processData.getId()));
        String processType = DictUtils.getDictLabel("process_type", processData.getProcessType());
        List<ProcessDataDTO.Parameter> parameterList = null;
        if (processData.getTechnicalParameter() != null && !processData.getTechnicalParameter().isEmpty()) {
            JSONArray jsonArray = JSON.parseArray(processData.getTechnicalParameter());
            parameterList = jsonArray.toList(ProcessDataDTO.Parameter.class);
        }

        return ProcessDataVo.builder()
                .id(processData.getId())
                .processCode(processData.getProcessCode())
                .processName(processData.getProcessName())
                .categoryId(processData.getCategoryId())
                .categoryName(processCategory.getCategoryName())
                .processType(processData.getProcessType())
                .processTypeName(processType)
                .workOrderReporting(processData.getWorkOrderReporting())
                .processImages(processData.getProcessImages())
                .processAttachments(processData.getProcessAttachments())
                .standardWorkingHours(processData.getStandardWorkingHours())
                .auxiliaryWorkingHours(processData.getAuxiliaryWorkingHours())
                .processCost(processData.getProcessCost())
                .processAttachments(processData.getProcessAttachments())
                .technicalParameter(processData.getTechnicalParameter())
                .technicalParameterList(parameterList)
                .processStationRelationList(processStationRelations)
                .processMaterialRelationList(processMaterialRelations)
                .delFlag(processData.getDelFlag())
                .version(processData.getVersion())
                .createBy(processData.getCreateBy())
                .createTime(processData.getCreateTime())
                .updateBy(processData.getUpdateBy())
                .updateTime(processData.getUpdateTime())
                .remark(processData.getRemark())
                .build();
    }

    @Override
    public List<ProcessDataVo> selectProcessDataByIds(List<Long> ids) {
        List<ProcessData> processDataList = processDataMapper.selectList(new QueryWrapper<ProcessData>().lambda()
                .in(ProcessData::getId, ids));
        List<ProcessDataVo> processDataVos = processDataList.stream().map(processData -> {
            ProcessCategory processCategory = processCategoryMapper.selectProcessCategoryById(processData.getCategoryId());
            List<ProcessStationRelation> processStationRelations = processStationRelationMapper.selectList(new QueryWrapper<ProcessStationRelation>().lambda()
                    .eq(ProcessStationRelation::getProcessId, processData.getId()));
            List<ProcessMaterialRelation> processMaterialRelations = processMaterialRelationMapper.selectList(new QueryWrapper<ProcessMaterialRelation>().lambda()
                    .eq(ProcessMaterialRelation::getProcessId, processData.getId()));
            String processType = DictUtils.getDictLabel("process_type", processData.getProcessType());
            List<ProcessDataDTO.Parameter> parameterList = null;
            if (processData.getTechnicalParameter() != null && !processData.getTechnicalParameter().isEmpty()) {
                JSONArray jsonArray = JSON.parseArray(processData.getTechnicalParameter());
                parameterList = jsonArray.toList(ProcessDataDTO.Parameter.class);
            }
            return ProcessDataVo.builder()
                    .id(processData.getId())
                    .processCode(processData.getProcessCode())
                    .processName(processData.getProcessName())
                    .categoryId(processData.getCategoryId())
                    .categoryName(processCategory.getCategoryName())
                    .processType(processData.getProcessType())
                    .processTypeName(processType)
                    .workOrderReporting(processData.getWorkOrderReporting())
                    .processImages(processData.getProcessImages())
                    .processAttachments(processData.getProcessAttachments())
                    .standardWorkingHours(processData.getStandardWorkingHours())
                    .auxiliaryWorkingHours(processData.getAuxiliaryWorkingHours())
                    .processCost(processData.getProcessCost())
                    .processAttachments(processData.getProcessAttachments())
                    .technicalParameter(processData.getTechnicalParameter())
                    .technicalParameterList(parameterList)
                    .processStationRelationList(processStationRelations)
                    .processMaterialRelationList(processMaterialRelations)
                    .delFlag(processData.getDelFlag())
                    .version(processData.getVersion())
                    .createBy(processData.getCreateBy())
                    .createTime(processData.getCreateTime())
                    .updateBy(processData.getUpdateBy())
                    .updateTime(processData.getUpdateTime())
                    .remark(processData.getRemark())
                    .build();
        }).collect(Collectors.toList());
        return processDataVos;
    }

    /**
     * 查询工序信息列表
     *
     * @param processData 工序信息
     * @return 工序信息
     */
    @Override
    public List<ProcessDataVo> selectProcessDataList(ProcessData processData) {
        List<ProcessData> processDataList = processDataMapper.selectProcessDataList(processData);
        List<ProcessDataVo> processDataVos = processDataList.stream().map(item -> {
            ProcessCategory processCategory = processCategoryMapper.selectProcessCategoryById(item.getCategoryId());
            List<ProcessStationRelation> processStationRelations = processStationRelationMapper.selectList(new QueryWrapper<ProcessStationRelation>().lambda()
                    .eq(ProcessStationRelation::getProcessId, item.getId()));
            List<ProcessMaterialRelation> processMaterialRelations = processMaterialRelationMapper.selectList(new QueryWrapper<ProcessMaterialRelation>().lambda()
                    .eq(ProcessMaterialRelation::getProcessId, item.getId()));
            String processType = DictUtils.getDictLabel("process_type", item.getProcessType());
            List<ProcessDataDTO.Parameter> parameterList = null;
            if (item.getTechnicalParameter() != null && !item.getTechnicalParameter().isEmpty()) {
                JSONArray jsonArray = JSON.parseArray(item.getTechnicalParameter());
                parameterList = jsonArray.toList(ProcessDataDTO.Parameter.class);
            }
            return ProcessDataVo.builder()
                    .id(item.getId())
                    .processCode(item.getProcessCode())
                    .processName(item.getProcessName())
                    .categoryId(item.getCategoryId())
                    .categoryName(processCategory.getCategoryName())
                    .processType(item.getProcessType())
                    .processTypeName(processType)
                    .workOrderReporting(item.getWorkOrderReporting())
                    .processImages(item.getProcessImages())
                    .processAttachments(item.getProcessAttachments())
                    .standardWorkingHours(item.getStandardWorkingHours())
                    .auxiliaryWorkingHours(item.getAuxiliaryWorkingHours())
                    .processCost(item.getProcessCost())
                    .technicalParameter(item.getTechnicalParameter())
                    .technicalParameterList(parameterList)
                    .processStationRelationList(processStationRelations)
                    .processMaterialRelationList(processMaterialRelations)
                    .delFlag(item.getDelFlag())
                    .version(item.getVersion())
                    .createBy(item.getCreateBy())
                    .createTime(item.getCreateTime())
                    .updateBy(item.getUpdateBy())
                    .updateTime(item.getUpdateTime())
                    .remark(item.getRemark())
                    .build();
        }).collect(Collectors.toList());
        Page<ProcessData> queryData=(Page<ProcessData>)processDataList;
        Page<ProcessDataVo> page = new Page<>(queryData.getPageNum(), queryData.getPageSize());
        page.setTotal(queryData.getTotal());
        page.addAll(processDataVos);
        return page;
    }

    /**
     * 新增工序信息
     *
     * @param processDataDTO 工序信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertProcessData(ProcessDataDTO processDataDTO) {
        processDataDTO.setCreateTime(DateUtils.getNowDate());
        ProcessData processData = new ProcessData();
        BeanUtils.copyProperties(processDataDTO, processData);
        if (processDataDTO.getTechnicalParameterList() != null && !processDataDTO.getTechnicalParameterList().isEmpty()) {
            // 转换成json字符串
            processData.setTechnicalParameter(JSON.toJSONString(processDataDTO.getTechnicalParameterList()));
        }else {
            processData.setTechnicalParameter(null);
        }
        int i = processDataMapper.insertProcessData(processData);
        processDataDTO.setId(processData.getId());
        //将数据新增到工序工位关联表中
        if (processDataDTO.getProcessStationRelationList() != null && !processDataDTO.getProcessStationRelationList().isEmpty()) {
            processDataDTO.getProcessStationRelationList().forEach(workstation -> {
                ProcessStationRelation processStationRelation = new ProcessStationRelation();
                processStationRelation.setProcessId(processData.getId());
                processStationRelation.setStationId(workstation.getStationId());
                processStationRelation.setStationCode(workstation.getStationCode());
                processStationRelation.setStationName(workstation.getStationName());
                processStationRelation.setWorkshopId(workstation.getWorkshopId());
                processStationRelation.setWorkshopName(workstation.getWorkshopName());
                processStationRelation.setProductionLineId(workstation.getProductionLineId());
                processStationRelation.setProductionLineName(workstation.getProductionLineName());
                processStationRelation.setFactoryId(workstation.getFactoryId());
                processStationRelation.setFactoryName(workstation.getFactoryName());
                processStationRelation.setEquipmentId(workstation.getEquipmentId());
                processStationRelation.setEquipmentName(workstation.getEquipmentName());
                processStationRelation.setCreateBy(processData.getCreateBy());
                processStationRelation.setCreateTime(DateUtils.getNowDate());
                processStationRelationMapper.insertProcessStationRelation(processStationRelation);
            });
        }
        //将数据新增到工序物料关联表中
        if (processDataDTO.getProcessMaterialRelationList() != null && !processDataDTO.getProcessMaterialRelationList().isEmpty()) {
            processDataDTO.getProcessMaterialRelationList().forEach(material -> {
                ProcessMaterialRelation processMaterialRelation = new ProcessMaterialRelation();
                processMaterialRelation.setProcessId(processData.getId());
                processMaterialRelation.setMaterialId(material.getMaterialId());
                processMaterialRelation.setMaterialName(material.getMaterialName());
                processMaterialRelation.setMaterialCode(material.getMaterialCode());
                processMaterialRelation.setMaterialCategoryId(material.getMaterialCategoryId());
                processMaterialRelation.setMaterialCategoryName(material.getMaterialCategoryName());
                processMaterialRelation.setMaterialTypeId(material.getMaterialTypeId());
                processMaterialRelation.setMaterialTypeName(material.getMaterialTypeName());
                processMaterialRelation.setManufacturingMethodId(material.getManufacturingMethodId());
                processMaterialRelation.setManufacturingMethodName(material.getManufacturingMethodName());
                processMaterialRelation.setMaterialUnitId(material.getMaterialUnitId());
                processMaterialRelation.setMaterialUnitName(material.getMaterialUnitName());
                processMaterialRelation.setMaterialSpecification(material.getMaterialSpecification());
                processMaterialRelation.setMaterialUsedQuantity(material.getMaterialUsedQuantity());
                processMaterialRelation.setCreateBy(processData.getCreateBy());
                processMaterialRelation.setCreateTime(DateUtils.getNowDate());
                processMaterialRelationMapper.insertProcessMaterialRelation(processMaterialRelation);
            });
        }
        return i;
    }

    /**
     * 修改工序信息
     *
     * @param processDataDTO 工序信息
     * @return 结果
     */
    @Transactional
    @Override
    public int updateProcessData(ProcessDataDTO processDataDTO) {
        processDataDTO.setUpdateTime(DateUtils.getNowDate());
        ProcessData processData = new ProcessData();
        BeanUtils.copyProperties(processDataDTO, processData);
        if (processDataDTO.getTechnicalParameterList() != null && !processDataDTO.getTechnicalParameterList().isEmpty()) {
            // 转换成json字符串
            processData.setTechnicalParameter(JSON.toJSONString(processDataDTO.getTechnicalParameterList()));
        }else {
            processData.setTechnicalParameter(null);
        }
        int i = processDataMapper.updateProcessData(processData);
        if (i > 0) {
            processStationRelationMapper.delete(new QueryWrapper<ProcessStationRelation>().lambda()
                    .eq(ProcessStationRelation::getProcessId, processDataDTO.getId()));
            processMaterialRelationMapper.delete(new QueryWrapper<ProcessMaterialRelation>().lambda()
                    .eq(ProcessMaterialRelation::getProcessId, processDataDTO.getId()));
            //将数据新增到工序工位关联表中
            if (processDataDTO.getProcessStationRelationList() != null && !processDataDTO.getProcessStationRelationList().isEmpty()) {
                processDataDTO.getProcessStationRelationList().forEach(workstation -> {
                    ProcessStationRelation processStationRelation = new ProcessStationRelation();
                    processStationRelation.setProcessId(processData.getId());
                    processStationRelation.setStationId(workstation.getStationId());
                    processStationRelation.setStationCode(workstation.getStationCode());
                    processStationRelation.setStationName(workstation.getStationName());
                    processStationRelation.setWorkshopId(workstation.getWorkshopId());
                    processStationRelation.setWorkshopName(workstation.getWorkshopName());
                    processStationRelation.setProductionLineId(workstation.getProductionLineId());
                    processStationRelation.setProductionLineName(workstation.getProductionLineName());
                    processStationRelation.setFactoryId(workstation.getFactoryId());
                    processStationRelation.setFactoryName(workstation.getFactoryName());
                    processStationRelation.setEquipmentId(workstation.getEquipmentId());
                    processStationRelation.setEquipmentName(workstation.getEquipmentName());
                    processStationRelation.setCreateBy(processData.getCreateBy());
                    processStationRelation.setCreateTime(DateUtils.getNowDate());
                    processStationRelationMapper.insertProcessStationRelation(processStationRelation);
                });
            }
            //将数据新增到工序物料关联表中
            if (processDataDTO.getProcessMaterialRelationList() != null && !processDataDTO.getProcessMaterialRelationList().isEmpty()) {
                processDataDTO.getProcessMaterialRelationList().forEach(material -> {
                    ProcessMaterialRelation processMaterialRelation = new ProcessMaterialRelation();
                    processMaterialRelation.setProcessId(processData.getId());
                    processMaterialRelation.setMaterialId(material.getMaterialId());
                    processMaterialRelation.setMaterialName(material.getMaterialName());
                    processMaterialRelation.setMaterialCode(material.getMaterialCode());
                    processMaterialRelation.setMaterialCategoryId(material.getMaterialCategoryId());
                    processMaterialRelation.setMaterialCategoryName(material.getMaterialCategoryName());
                    processMaterialRelation.setMaterialTypeId(material.getMaterialTypeId());
                    processMaterialRelation.setMaterialTypeName(material.getMaterialTypeName());
                    processMaterialRelation.setManufacturingMethodId(material.getManufacturingMethodId());
                    processMaterialRelation.setManufacturingMethodName(material.getManufacturingMethodName());
                    processMaterialRelation.setMaterialUnitId(material.getMaterialUnitId());
                    processMaterialRelation.setMaterialUnitName(material.getMaterialUnitName());
                    processMaterialRelation.setMaterialSpecification(material.getMaterialSpecification());
                    processMaterialRelation.setMaterialUsedQuantity(material.getMaterialUsedQuantity());
                    processMaterialRelation.setCreateBy(processData.getCreateBy());
                    processMaterialRelation.setCreateTime(DateUtils.getNowDate());
                    processMaterialRelationMapper.insertProcessMaterialRelation(processMaterialRelation);
                });
            }
        }
        return i;
    }

    /**
     * 批量删除工序信息
     *
     * @param ids 需要删除的工序信息主键
     * @return 结果
     */
    @Override
    public int deleteProcessDataByIds(Long[] ids) {
        int i = processDataMapper.deleteBatchIds(Arrays.stream(ids).collect(Collectors.toList()));
        if (ids.length > 0 && i > 0) {
            processStationRelationMapper.delete(new QueryWrapper<ProcessStationRelation>().lambda()
                    .in(ProcessStationRelation::getProcessId, ids));
            processMaterialRelationMapper.delete(new QueryWrapper<ProcessMaterialRelation>().lambda()
                    .in(ProcessMaterialRelation::getProcessId, ids));
        }
        return i;
    }

    /**
     * 删除工序信息信息
     *
     * @param id 工序信息主键
     * @return 结果
     */
    @Override
    public int deleteProcessDataById(Long id) {
        return processDataMapper.deleteProcessDataById(id);
    }
}